<!--
  * @file ClassDetail.vue
  * @description 班级详情页面组件，展示班级详细信息和学生列表
  * @created 2024-07-02
-->
<template>
  <div class="class-detail-container">
    <div class="header">
      <button @click="goBack" class="back-button">&larr; 返回学院</button>
      <h1>班级详情：{{ classInfo.name || '加载中...' }} <span v-if="usingMockData && !loadingClassInfo" style="color: orange; font-size: 0.8em;">(模拟数据)</span></h1>
    </div>

    <div class="info-section" v-if="!loadingClassInfo">
      <h2>基本信息</h2>
      <p><strong>班级ID:</strong> {{ props.classId }}</p>
      <p><strong>学院ID:</strong> {{ props.collegeId }}</p>
      <p><strong>班级名称:</strong> {{ classInfo.name || 'N/A' }}</p>
      <p><strong>年级:</strong> {{ classInfo.grade_name || 'N/A' }}</p>
      <p><strong>系部:</strong> {{ classInfo.department_name || 'N/A' }}</p> 
      <p><strong>班主任:</strong> {{ classInfo.teacher_name || 'N/A' }}</p>
      <p><strong>学生人数:</strong> {{ students.length }}</p>
    </div>
    <div v-else class="loading-placeholder">班级信息加载中...</div>

    <div class="students-section">
      <div class="section-header">
        <h2>学生列表</h2>
        <button @click="showAddStudentDialog" class="add-button">添加学生</button>
      </div>
      
      <div v-if="loadingStudents && !usingMockData" class="loading-placeholder">正在加载学生列表...</div>
      <div v-else-if="students.length > 0">
        <div class="table-filters">
          <input type="text" v-model="studentSearchText" placeholder="搜索学生..." class="search-input">
        </div>
        <table>
          <thead>
            <tr>
              <th>学号</th>
              <th>姓名</th>
              <th>性别</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="student in filteredStudents" :key="student.id">
              <td>{{ student.student_code || 'N/A' }}</td>
              <td>{{ student.name || 'N/A' }}</td>
              <td>{{ student.gender || 'N/A' }}</td>
              <td class="actions">
                <button @click="editStudent(student)" class="edit-button">编辑</button>
                <button @click="confirmDeleteStudent(student)" class="delete-button">删除</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <div v-else>
        <p class="empty-data">暂无学生数据<span v-if="!usingMockData && !loadingStudents">（或班级不存在 / 无学生记录）</span>。
          <button @click="showAddStudentDialog" class="add-button small">添加第一个学生</button>
        </p>
      </div>
    </div>

    <!-- 学情分析区域 -->
    <div class="analysis-section" :class="{'disabled': students.length === 0}">
      <h2>学情分析 <span v-if="usingMockData && !loadingAnalysis" style="color: orange; font-size: 0.8em;">(模拟数据)</span></h2>
      <div v-if="loadingAnalysis" class="loading-placeholder">学情数据加载中...</div>
      <div v-else-if="students.length === 0" class="empty-analysis">
        <p>班级中没有学生，无法生成学情分析。请先添加学生。</p>
      </div>
      <div v-else class="analysis-grid">
        <div class="chart-container average-scores-container">
          <h3>各科平均分</h3>
          <div class="chart-wrapper" style="height: 300px;">
            <canvas id="averageScoresChart"></canvas>
          </div>
        </div>
        <div class="chart-container grade-distribution-container">
          <h3>成绩等级分布</h3>
          <div class="chart-wrapper" style="height: 300px;">
            <canvas id="gradeDistributionChart"></canvas>
          </div>
        </div>
        <div class="rate-container">
          <h3>出勤率</h3>
          <div class="rate-value">{{ attendanceRate.toFixed(1) }}%</div>
        </div>
        <div class="rate-container">
          <h3>作业提交率</h3>
          <div class="rate-value">{{ assignmentCompletionRate.toFixed(1) }}%</div>
        </div>
      </div>
    </div>

    <!-- 添加/编辑学生对话框 -->
    <div v-if="showStudentDialog" class="dialog-overlay" @click.self="cancelStudentDialog">
      <div class="dialog">
        <h2>{{ isEditMode ? '编辑学生' : '添加学生' }}</h2>
        <form @submit.prevent="submitStudentForm">
          <div class="form-group">
            <label for="studentCode">学号 <span class="required">*</span></label>
            <input 
              id="studentCode" 
              v-model="studentForm.student_code" 
              type="text" 
              required 
              :disabled="isEditMode"
              placeholder="请输入学号"
            >
          </div>
          <div class="form-group">
            <label for="studentName">姓名 <span class="required">*</span></label>
            <input 
              id="studentName" 
              v-model="studentForm.name" 
              type="text" 
              required 
              placeholder="请输入学生姓名"
            >
          </div>
          <div class="form-group">
            <label for="studentGender">性别</label>
            <select id="studentGender" v-model="studentForm.gender">
              <option value="">请选择</option>
              <option value="男">男</option>
              <option value="女">女</option>
            </select>
          </div>
          <div class="form-group">
            <label for="studentDate">入学日期</label>
            <input 
              id="studentDate" 
              v-model="studentForm.enrollment_date" 
              type="date"
            >
          </div>
          <div class="form-actions">
            <button type="button" @click="cancelStudentDialog" class="cancel-button">取消</button>
            <button type="submit" class="submit-button" :disabled="isSubmitting">
              {{ isSubmitting ? '提交中...' : (isEditMode ? '保存' : '添加') }}
            </button>
          </div>
        </form>
      </div>
    </div>

    <!-- 删除确认对话框 -->
    <div v-if="showDeleteDialog" class="dialog-overlay" @click.self="cancelDeleteDialog">
      <div class="dialog confirm-dialog">
        <h3>确认删除</h3>
        <p>确定要删除学生 "{{ studentToDelete?.name || '未知学生' }}" ({{ studentToDelete?.student_code || '' }}) 吗？此操作不可恢复。</p>
        <div class="form-actions">
          <button @click="cancelDeleteDialog" class="cancel-button">取消</button>
          <button @click="deleteSelectedStudent" class="delete-button" :disabled="isDeleting">
            {{ isDeleting ? '删除中...' : '确认删除' }}
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getYzhClassDetail, getYzhClassStudents } from '@/api/admin/yzhTeacher'
import { addStudent, updateStudent, deleteStudent } from '@/api/admin/yzhTeacher'
import { Chart, registerables } from 'chart.js'
Chart.register(...registerables)

const route = useRoute()
const router = useRouter()

// 从路由参数获取 props
const props = defineProps({
  collegeId: {
    type: [String, Number],
    required: true
  },
  classId: {
    type: [String, Number],
    required: true
  }
})

const classInfo = ref({})
const students = ref([])
const loadingClassInfo = ref(false)
const loadingStudents = ref(false)
const usingMockData = ref(false)
const studentSearchText = ref('')

// 计算过滤后的学生列表
const filteredStudents = computed(() => {
  if (!studentSearchText.value) return students.value
  
  const searchText = studentSearchText.value.toLowerCase()
  return students.value.filter(student => 
    (student.name && student.name.toLowerCase().includes(searchText)) ||
    (student.student_code && student.student_code.toLowerCase().includes(searchText))
  )
})

// 学生表单相关
const showStudentDialog = ref(false)
const isEditMode = ref(false)
const isSubmitting = ref(false)
const studentForm = ref({
  student_code: '',
  name: '',
  gender: '',
  enrollment_date: new Date().toISOString().slice(0, 10),
  class_id: props.classId
})

// 删除学生相关
const showDeleteDialog = ref(false)
const studentToDelete = ref(null)
const isDeleting = ref(false)

const mockClassInfo = (classId) => ({
  id: classId,
  name: `模拟班级 ${classId}`,
  grade_name: '2024级',
  teacher_name: '模拟教师',
  college_id: props.collegeId,
  department_name: '模拟系部'
})

const mockStudents = () => ([
  { id: 'm1', student_code: 'MS001', name: '模拟学生甲', gender: '男' },
  { id: 'm2', student_code: 'MS002', name: '模拟学生乙', gender: '女' },
  { id: 'm3', student_code: 'MS003', name: '模拟学生丙', gender: '男' },
])

const averageScoresData = ref(null)
const gradeDistributionData = ref(null)
const attendanceRate = ref(0)
const assignmentCompletionRate = ref(0)
const loadingAnalysis = ref(false)

let averageScoresChart = null
let gradeDistributionChart = null

const generateMockAverageScores = (classId) => {
  const base = parseInt(classId.toString().slice(-1) || "0", 10) % 5
  return {
    labels: ['语文', '数学', '英语', '物理', '化学'],
    datasets: [{
      label: `班级 ${classId} 平均分`,
      data: [80 + base * 2, 75 + base * 3, 85 - base * 1, 70 + base * 4, 78 - base * 2],
      backgroundColor: 'rgba(54, 162, 235, 0.6)',
      borderColor: 'rgba(54, 162, 235, 1)',
      borderWidth: 1
    }]
  }
}

const generateMockGradeDistribution = (classId) => {
  const base = parseInt(classId.toString().slice(-2) || "0", 10) % 10
  return {
    labels: ['优秀 (90-100)', '良好 (80-89)', '中等 (70-79)', '及格 (60-69)', '不及格 (<60)'],
    datasets: [{
      label: '成绩分布',
      data: [15 + base, 25 - base, 30 + base / 2, 20 - base / 2, 10],
      backgroundColor: ['rgba(75, 192, 192, 0.7)', 'rgba(54, 162, 235, 0.7)', 'rgba(255, 206, 86, 0.7)', 'rgba(255, 159, 64, 0.7)', 'rgba(255, 99, 132, 0.7)'],
      hoverOffset: 4
    }]
  }
}

const generateMockRates = (classId) => {
  const base1 = parseInt(classId.toString().slice(-1) || "5", 10)
  const base2 = parseInt(classId.toString().slice(-2, -1) || "8", 10)
  return {
    attendance: Math.min(100, 85 + base1 + base2 / 2),
    assignment: Math.min(100, 80 + base2 + base1 / 2)
  }
}

const fetchLearningAnalysisData = async (classId) => {
  loadingAnalysis.value = true
  console.log(`Fetching (mock) learning analysis data for Class ID: ${classId}`)
  return new Promise(resolve => {
    setTimeout(() => {
      averageScoresData.value = generateMockAverageScores(classId)
      gradeDistributionData.value = generateMockGradeDistribution(classId)
      const rates = generateMockRates(classId)
      attendanceRate.value = rates.attendance
      assignmentCompletionRate.value = rates.assignment
      loadingAnalysis.value = false
      resolve()
    }, 1000)
  })
}

const renderAverageScoresChart = async () => {
  await nextTick()
  const ctx = document.getElementById('averageScoresChart')
  if (!ctx || !averageScoresData.value || students.value.length === 0) return
  if (averageScoresChart) averageScoresChart.destroy()
  averageScoresChart = new Chart(ctx, {
    type: 'bar',
    data: averageScoresData.value,
    options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, suggestedMax: 100 } } }
  })
}

const renderGradeDistributionChart = async () => {
  await nextTick()
  const ctx = document.getElementById('gradeDistributionChart')
  if (!ctx || !gradeDistributionData.value || students.value.length === 0) return
  if (gradeDistributionChart) gradeDistributionChart.destroy()
  gradeDistributionChart = new Chart(ctx, {
    type: 'pie',
    data: gradeDistributionData.value,
    options: { responsive: true, maintainAspectRatio: false }
  })
}

const fetchClassDetails = async () => {
  loadingClassInfo.value = true
  usingMockData.value = false
  try {
    const response = await getYzhClassDetail(props.classId)
    console.log('班级详情API返回：', response)
    
    // 不论是否有id字段，只要状态成功就使用返回数据
    if (response && response.status === 'success' && response.data) {
      console.log('班级详情有效，数据：', response.data)
      classInfo.value = response.data
      await fetchClassStudents() // 获取学生列表
    } else {
      console.warn('班级详情API返回异常:', response)
      classInfo.value = mockClassInfo(props.classId)
      students.value = mockStudents()
      usingMockData.value = true
    }
  } catch (error) {
    console.error('获取班级详情出错:', error)
    classInfo.value = { ...mockClassInfo(props.classId), name: '班级信息加载异常' }
    students.value = mockStudents()
    usingMockData.value = true
  } finally {
    loadingClassInfo.value = false
  }
}

// 在fetchClassStudents函数开头添加一个防抖标记
let refreshTimeout = null;

const fetchClassStudents = async (ignoreErrors = false) => {
  if (usingMockData.value && students.value.length > 0) { // If already using mock students, no need to fetch again unless empty
    loadingStudents.value = false
    return
  }
  
  if (refreshTimeout) {
    clearTimeout(refreshTimeout)
    refreshTimeout = null
  }
  
  loadingStudents.value = true
  try {
    const response = await getYzhClassStudents(props.classId)
    console.log('学生列表API返回：', response)
    
    if (response && response.status === 'success' && response.data) {
      console.log('学生数据格式：', response.data)
      
      // 检查students字段是否存在
      if (response.data.students !== undefined) {
        console.log('成功获取到真实学生数据:', response.data.students.length, '条记录')
        students.value = response.data.students
        usingMockData.value = false // 无论是否有学生，只要API返回成功，就不使用模拟数据
      } else {
        if (!ignoreErrors) {
          console.warn('返回数据中没有students字段:', Object.keys(response.data))
          students.value = mockStudents()
          usingMockData.value = true
        }
      }
    } else {
      if (!ignoreErrors) {
        console.warn('获取学生列表失败或格式不正确:', response)
        students.value = mockStudents()
        usingMockData.value = true
      }
    }
  } catch (error) {
    if (!ignoreErrors) {
      console.error('获取学生列表错误:', error)
      students.value = mockStudents()
      usingMockData.value = true
    }
  } finally {
    loadingStudents.value = false
  }
}

// 添加一个总是重试的函数
const alwaysRefreshStudents = () => {
  // 调用三次获取学生列表，增加成功概率
  refreshTimeout = setTimeout(() => {
    fetchClassStudents(true) // 第一次立即尝试，忽略错误
    
    refreshTimeout = setTimeout(() => {
      fetchClassStudents(true) // 1秒后再次尝试，忽略错误
      
      refreshTimeout = setTimeout(() => {
        fetchClassStudents(false) // 2秒后最后尝试，如果仍然失败，显示错误
      }, 1000)
    }, 1000)
  }, 0)
}

// 添加学生表单操作
const showAddStudentDialog = () => {
  isEditMode.value = false
  // 确保使用数字类型的班级ID
  const numericClassId = parseInt(props.classId, 10);
  console.log('添加学生 - 班级ID:', numericClassId);
  
  studentForm.value = {
    student_code: '',
    name: '',
    gender: '',
    enrollment_date: new Date().toISOString().slice(0, 10),
    class_id: numericClassId  // 确保使用数字类型
  }
  showStudentDialog.value = true
}

// 编辑学生
const editStudent = (student) => {
  isEditMode.value = true
  studentForm.value = { ...student }
  // 格式化日期
  if (student.enrollment_date) {
    try {
      // 尝试将各种可能的日期格式转换为yyyy-MM-dd
      const date = new Date(student.enrollment_date)
      if (!isNaN(date)) {
        studentForm.value.enrollment_date = date.toISOString().slice(0, 10)
      }
    } catch (e) {
      console.warn('无法解析日期格式:', e)
    }
  }
  showStudentDialog.value = true
}

// 取消学生表单
const cancelStudentDialog = () => {
  showStudentDialog.value = false
}

// 提交学生表单
const submitStudentForm = async () => {
  try {
    isSubmitting.value = true
    
    // 验证表单
    if (!studentForm.value.student_code || !studentForm.value.name) {
      alert('学号和姓名为必填项')
      return
    }
    
    // 确保班级ID是数字类型
    const numericClassId = parseInt(props.classId, 10);
    
    // 创建新的表单数据对象，只包含后端需要的字段
    const formData = {
      student_code: studentForm.value.student_code,
      name: studentForm.value.name,
      gender: studentForm.value.gender || '',
      enrollment_date: studentForm.value.enrollment_date,
      class_id: numericClassId
    }
    
    // 如果是编辑模式，添加ID
    if (isEditMode.value && studentForm.value.id) {
      formData.id = studentForm.value.id
    }
    
    console.log('提交学生表单，数据:', JSON.stringify(formData));
    
    let success = false;
    const operationType = isEditMode.value ? '更新' : '添加';
    
    try {
      // 设置一个标志，稍后我们会假设操作成功
      let assumeSuccess = false;
      
      if (isEditMode.value) {
        // 编辑模式
        const response = await updateStudent(formData.id, formData)
        console.log('更新学生响应:', response);
        if (response && response.status === 'success') {
          success = true;
          showStudentDialog.value = false
        } else {
          assumeSuccess = true; // 虽然返回非成功，但我们假设可能是成功的
        }
      } else {
        // 添加模式
        const response = await addStudent(formData)
        console.log('添加学生响应:', response);
        if (response && response.status === 'success') {
          success = true;
          showStudentDialog.value = false
        } else {
          assumeSuccess = true; // 虽然返回非成功，但我们假设可能是成功的
        }
      }
      
      // 如果假设成功，我们直接关闭对话框并刷新
      if (assumeSuccess) {
        showStudentDialog.value = false
        alert(`${operationType}请求已发送，但服务器返回异常。系统将自动刷新数据。`)
      } 
      // 如果确认成功，显示成功消息
      else if (success) {
        alert(`${operationType}学生成功`)
      }
      
    } catch (error) {
      console.error(`${operationType}学生请求出错:`, error);
      alert(`${operationType}请求出错，但可能已经成功。系统将自动刷新数据。`)
      showStudentDialog.value = false
    }
    
    // 无论请求是否异常，都自动刷新列表
    alwaysRefreshStudents();
    
    // 取消模拟数据模式
    if (usingMockData.value) {
      usingMockData.value = false;
    }
    
    // 更新图表
    setTimeout(() => {
      updateCharts();
    }, 2000);
    
  } catch (error) {
    console.error('提交学生表单失败:', error)
    alert(`操作失败，但可能已经生效。请检查最新数据。`)
  } finally {
    isSubmitting.value = false
  }
}

// 确认删除学生
const confirmDeleteStudent = (student) => {
  studentToDelete.value = student
  showDeleteDialog.value = true
}

// 取消删除
const cancelDeleteDialog = () => {
  showDeleteDialog.value = false
  studentToDelete.value = null
}

// 执行删除
const deleteSelectedStudent = async () => {
  if (!studentToDelete.value) return
  
  try {
    isDeleting.value = true
    
    try {
      const response = await deleteStudent(studentToDelete.value.id)
      if (response && response.status === 'success') {
        showDeleteDialog.value = false
        studentToDelete.value = null
        alert('删除学生成功')
      } else {
        // 尽管响应不成功，我们还是假设删除可能已经成功
        showDeleteDialog.value = false
        studentToDelete.value = null
        alert('删除请求已发送，但服务器返回异常。系统将自动刷新数据。')
      }
    } catch (error) {
      console.error('删除学生请求出错:', error);
      showDeleteDialog.value = false
      studentToDelete.value = null
      alert('删除请求出错，但可能已经成功。系统将自动刷新数据。')
    }
    
    // 无论成功失败，都尝试刷新数据
    alwaysRefreshStudents();
    
    // 更新图表
    setTimeout(() => {
      updateCharts();
    }, 2000);
    
  } catch (error) {
    console.error('删除学生失败:', error)
    alert(`删除操作失败，但可能已经生效。请检查最新数据。`)
  } finally {
    isDeleting.value = false
  }
}

// 更新图表
const updateCharts = async () => {
  // 如果班级有学生，渲染图表
  if (students.value.length > 0) {
    await renderAverageScoresChart()
    await renderGradeDistributionChart()
  } else {
    // 如果没有学生，销毁图表
    if (averageScoresChart) {
      averageScoresChart.destroy()
      averageScoresChart = null
    }
    if (gradeDistributionChart) {
      gradeDistributionChart.destroy()
      gradeDistributionChart = null
    }
  }
}

const goBack = () => {
  router.push(`/admin/college/${props.collegeId}`)
}

onMounted(async () => {
  console.log('班级详情页面加载，班级ID:', props.classId);
  await fetchClassDetails();
  console.log('班级详情和学生数据加载完成，是否使用模拟数据:', usingMockData.value);
  await fetchLearningAnalysisData(props.classId);
  // Only render charts if we have the canvas elements and data and students
  if (students.value.length > 0) {
    console.log('渲染图表，学生数量:', students.value.length);
    if (document.getElementById('averageScoresChart') && averageScoresData.value) {
      renderAverageScoresChart();
    }
    if (document.getElementById('gradeDistributionChart') && gradeDistributionData.value) {
      renderGradeDistributionChart();
    }
  }
})

onBeforeUnmount(() => {
  if (averageScoresChart) averageScoresChart.destroy()
  if (gradeDistributionChart) gradeDistributionChart.destroy()
})

</script>

<style scoped>
.class-detail-container { padding: 20px; background-color: #f9f9f9; }
.header { display: flex; align-items: center; margin-bottom: 20px; }
.back-button { background: #e0e0e0; border: none; padding: 8px 15px; border-radius: 5px; cursor: pointer; margin-right: 20px; font-size: 14px; }
.back-button:hover { background: #d0d0d0; }
.header h1 { margin: 0; font-size: 24px; }
.info-section, .students-section, .analysis-section { background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.info-section h2, .students-section h2, .analysis-section h2, .section-header h2 { margin-top: 0; margin-bottom: 15px; font-size: 20px; border-bottom: 1px solid #eee; padding-bottom: 10px; }
.info-section p { margin: 8px 0; font-size: 15px; color: #333; }
.info-section p strong { color: #555; min-width: 80px; display: inline-block; }
table { width: 100%; border-collapse: collapse; }
thead tr { background-color: #f0f0f0; border-bottom: 2px solid #ddd; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid #eee; }
th { font-weight: bold; color: #333; }
tbody tr:hover { background-color: #f9f9f9; }

/* 学情分析区域 */
.loading-placeholder {
  text-align: center;
  padding: 40px;
  color: #666;
  font-size: 18px;
}

.analysis-grid {
  display: grid;
  grid-template-columns: 1fr 1fr; /* 两列布局 */
  gap: 20px;
}

.chart-container, .rate-container {
  background-color: #f8f9fa; /* 轻微的背景色以区分 */
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}

.chart-container h3, .rate-container h3 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 17px; /* 稍小一点的标题 */
  text-align: center;
  color: #333;
}

.chart-wrapper {
  position: relative; 
  width: 100%;
  /* height is set inline in template for canvas parent */
}

.rate-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center; /* 垂直居中内容 */
  min-height: 150px; /* 给一些最小高度 */
}

.rate-value {
  font-size: 2.8em; /* 更大的数字 */
  font-weight: bold;
  color: #007bff; /* 统一用蓝色主题色 */
  text-align: center;
  margin-top: 10px; /* 与标题间距 */
}

/* 学情分析区域 - 禁用状态 */
.analysis-section.disabled {
  opacity: 0.7;
  position: relative;
}

.empty-analysis {
  text-align: center;
  padding: 40px 20px;
  font-size: 16px;
  color: #666;
  background-color: #f8f9fa;
  border-radius: 8px;
}

/* 学生管理相关样式 */
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.add-button {
  background-color: #4CAF50;
  color: white;
  border: none;
  padding: 8px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.add-button:hover {
  background-color: #45a049;
}

.add-button.small {
  font-size: 13px;
  padding: 6px 12px;
  margin-left: 10px;
}

.edit-button {
  background-color: #2196F3;
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 13px;
  margin-right: 5px;
}

.edit-button:hover {
  background-color: #0b7dda;
}

.delete-button {
  background-color: #f44336;
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 13px;
}

.delete-button:hover {
  background-color: #d32f2f;
}

.table-filters {
  margin-bottom: 15px;
  display: flex;
  justify-content: flex-end;
}

.search-input {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  width: 250px;
  font-size: 14px;
}

.actions {
  white-space: nowrap;
  text-align: right;
}

/* 对话框样式 */
.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.dialog {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  width: 500px;
  max-width: 95%;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.confirm-dialog {
  width: 400px;
}

.dialog h2 {
  margin-top: 0;
  margin-bottom: 20px;
  font-size: 20px;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}

.dialog h3 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 18px;
  color: #333;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-size: 14px;
  color: #555;
}

.form-group input, .form-group select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.form-group input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

.form-actions {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.cancel-button {
  background-color: #e0e0e0;
  border: none;
  padding: 8px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.submit-button {
  background-color: #2196F3;
  color: white;
  border: none;
  padding: 8px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.submit-button:hover {
  background-color: #0b7dda;
}

.submit-button:disabled {
  background-color: #a0a0a0;
  cursor: not-allowed;
}

.required {
  color: #f44336;
}

.empty-data {
  text-align: center;
  padding: 20px;
  color: #666;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .analysis-grid {
    grid-template-columns: 1fr; /* 单列 */
  }
  .chart-container, .rate-container {
    width: 100%; /* 占满整行 */
  }
}
</style> 
 